package tunnel

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"log"
	"math/big"
	"net"
	"time"
)

// GenerateSelfSignedCertForQUIC 为 QUIC 生成自签名证书
func GenerateSelfSignedCertForQUIC() (tls.Certificate, error) {
	// 生成 RSA 私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return tls.Certificate{}, err
	}

	// 创建证书模板
	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Organization: []string{"InternalNetBridge QUIC"},
			CommonName:   "localhost",
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().Add(365 * 24 * time.Hour), // 1年有效期
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
		DNSNames:              []string{"localhost", "*.localhost"},
		IPAddresses: []net.IP{
			net.ParseIP("127.0.0.1"),
			net.ParseIP("::1"),
		},
	}

	// 创建证书
	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
	if err != nil {
		return tls.Certificate{}, err
	}

	// 编码证书
	certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})

	// 加载证书
	cert, err := tls.X509KeyPair(certPEM, keyPEM)
	if err != nil {
		return tls.Certificate{}, err
	}

	log.Printf("✅ [QUIC TLS] 生成自签名证书成功")
	log.Printf("   ├─ CommonName: localhost")
	log.Printf("   ├─ 有效期: 1年")
	log.Printf("   └─ 支持 IP: 127.0.0.1, ::1")

	return cert, nil
}

// LoadQUICTLSConfig 加载 QUIC TLS 配置
func LoadQUICTLSConfig() (*tls.Config, error) {
	// TODO: 生产环境应该从文件加载证书
	// cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")

	// 开发环境：使用自签名证书
	cert, err := GenerateSelfSignedCertForQUIC()
	if err != nil {
		return nil, err
	}

	return &tls.Config{
		Certificates: []tls.Certificate{cert},
		MinVersion:   tls.VersionTLS13,      // QUIC 必须使用 TLS 1.3
		NextProtos:   []string{"h3-tunnel"}, // ALPN 协议名
		// 开发环境：关闭客户端证书验证
		ClientAuth: tls.NoClientCert,
	}, nil
}

// LoadQUICTLSConfigForClient 加载客户端 TLS 配置
func LoadQUICTLSConfigForClient() *tls.Config {
	return &tls.Config{
		InsecureSkipVerify: true, // 开发环境：跳过证书验证
		MinVersion:         tls.VersionTLS13,
		NextProtos:         []string{"h3-tunnel"},
	}
}
